﻿using System;
using System.Threading;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x0200006F RID: 111
	public sealed class GenericParameter : TypeReference, ICustomAttributeProvider, IMetadataTokenProvider
	{
		// Token: 0x170000D1 RID: 209
		// (get) Token: 0x0600047E RID: 1150 RVA: 0x0001C42C File Offset: 0x0001A62C
		// (set) Token: 0x0600047F RID: 1151 RVA: 0x00003C0F File Offset: 0x00001E0F
		public GenericParameterAttributes Attributes
		{
			get
			{
				return (GenericParameterAttributes)this.attributes;
			}
			set
			{
				this.attributes = (ushort)value;
			}
		}

		// Token: 0x170000D2 RID: 210
		// (get) Token: 0x06000480 RID: 1152 RVA: 0x0001C444 File Offset: 0x0001A644
		public int Position
		{
			get
			{
				return this.position;
			}
		}

		// Token: 0x170000D3 RID: 211
		// (get) Token: 0x06000481 RID: 1153 RVA: 0x0001C45C File Offset: 0x0001A65C
		public GenericParameterType Type
		{
			get
			{
				return this.type;
			}
		}

		// Token: 0x170000D4 RID: 212
		// (get) Token: 0x06000482 RID: 1154 RVA: 0x0001C474 File Offset: 0x0001A674
		public IGenericParameterProvider Owner
		{
			get
			{
				return this.owner;
			}
		}

		// Token: 0x170000D5 RID: 213
		// (get) Token: 0x06000483 RID: 1155 RVA: 0x0001C48C File Offset: 0x0001A68C
		public bool HasConstraints
		{
			get
			{
				bool flag = this.constraints != null;
				bool result;
				if (flag)
				{
					result = (this.constraints.Count > 0);
				}
				else
				{
					bool flag2;
					if (base.HasImage)
					{
						flag2 = this.Module.Read<GenericParameter, bool>(this, (GenericParameter generic_parameter, MetadataReader reader) => reader.HasGenericConstraints(generic_parameter));
					}
					else
					{
						flag2 = false;
					}
					result = flag2;
				}
				return result;
			}
		}

		// Token: 0x170000D6 RID: 214
		// (get) Token: 0x06000484 RID: 1156 RVA: 0x0001C4F4 File Offset: 0x0001A6F4
		public Collection<GenericParameterConstraint> Constraints
		{
			get
			{
				bool flag = this.constraints != null;
				Collection<GenericParameterConstraint> result;
				if (flag)
				{
					result = this.constraints;
				}
				else
				{
					bool hasImage = base.HasImage;
					if (hasImage)
					{
						result = this.Module.Read<GenericParameter, GenericParameterConstraintCollection>(ref this.constraints, this, (GenericParameter generic_parameter, MetadataReader reader) => reader.ReadGenericConstraints(generic_parameter));
					}
					else
					{
						Interlocked.CompareExchange<GenericParameterConstraintCollection>(ref this.constraints, new GenericParameterConstraintCollection(this), null);
						result = this.constraints;
					}
				}
				return result;
			}
		}

		// Token: 0x170000D7 RID: 215
		// (get) Token: 0x06000485 RID: 1157 RVA: 0x0001C574 File Offset: 0x0001A774
		public bool HasCustomAttributes
		{
			get
			{
				bool flag = this.custom_attributes != null;
				bool result;
				if (flag)
				{
					result = (this.custom_attributes.Count > 0);
				}
				else
				{
					result = this.GetHasCustomAttributes(this.Module);
				}
				return result;
			}
		}

		// Token: 0x170000D8 RID: 216
		// (get) Token: 0x06000486 RID: 1158 RVA: 0x0001C5B0 File Offset: 0x0001A7B0
		public Collection<CustomAttribute> CustomAttributes
		{
			get
			{
				return this.custom_attributes ?? this.GetCustomAttributes(ref this.custom_attributes, this.Module);
			}
		}

		// Token: 0x170000D9 RID: 217
		// (get) Token: 0x06000487 RID: 1159 RVA: 0x0001C5E0 File Offset: 0x0001A7E0
		// (set) Token: 0x06000488 RID: 1160 RVA: 0x00002AA0 File Offset: 0x00000CA0
		public override IMetadataScope Scope
		{
			get
			{
				bool flag = this.owner == null;
				IMetadataScope result;
				if (flag)
				{
					result = null;
				}
				else
				{
					result = ((this.owner.GenericParameterType == GenericParameterType.Method) ? ((MethodReference)this.owner).DeclaringType.Scope : ((TypeReference)this.owner).Scope);
				}
				return result;
			}
			set
			{
				throw new InvalidOperationException();
			}
		}

		// Token: 0x170000DA RID: 218
		// (get) Token: 0x06000489 RID: 1161 RVA: 0x0001C638 File Offset: 0x0001A838
		// (set) Token: 0x0600048A RID: 1162 RVA: 0x00002AA0 File Offset: 0x00000CA0
		public override TypeReference DeclaringType
		{
			get
			{
				return this.owner as TypeReference;
			}
			set
			{
				throw new InvalidOperationException();
			}
		}

		// Token: 0x170000DB RID: 219
		// (get) Token: 0x0600048B RID: 1163 RVA: 0x0001C658 File Offset: 0x0001A858
		public MethodReference DeclaringMethod
		{
			get
			{
				return this.owner as MethodReference;
			}
		}

		// Token: 0x170000DC RID: 220
		// (get) Token: 0x0600048C RID: 1164 RVA: 0x0001C678 File Offset: 0x0001A878
		public override ModuleDefinition Module
		{
			get
			{
				return this.module ?? this.owner.Module;
			}
		}

		// Token: 0x170000DD RID: 221
		// (get) Token: 0x0600048D RID: 1165 RVA: 0x0001C6A0 File Offset: 0x0001A8A0
		public override string Name
		{
			get
			{
				bool flag = !string.IsNullOrEmpty(base.Name);
				string result;
				if (flag)
				{
					result = base.Name;
				}
				else
				{
					result = (base.Name = ((this.type == GenericParameterType.Method) ? "!!" : "!") + this.position.ToString());
				}
				return result;
			}
		}

		// Token: 0x170000DE RID: 222
		// (get) Token: 0x0600048E RID: 1166 RVA: 0x0001A928 File Offset: 0x00018B28
		// (set) Token: 0x0600048F RID: 1167 RVA: 0x00002AA0 File Offset: 0x00000CA0
		public override string Namespace
		{
			get
			{
				return string.Empty;
			}
			set
			{
				throw new InvalidOperationException();
			}
		}

		// Token: 0x170000DF RID: 223
		// (get) Token: 0x06000490 RID: 1168 RVA: 0x0001C6FC File Offset: 0x0001A8FC
		public override string FullName
		{
			get
			{
				return this.Name;
			}
		}

		// Token: 0x170000E0 RID: 224
		// (get) Token: 0x06000491 RID: 1169 RVA: 0x0000A3A0 File Offset: 0x000085A0
		public override bool IsGenericParameter
		{
			get
			{
				return true;
			}
		}

		// Token: 0x170000E1 RID: 225
		// (get) Token: 0x06000492 RID: 1170 RVA: 0x0000A3A0 File Offset: 0x000085A0
		public override bool ContainsGenericParameter
		{
			get
			{
				return true;
			}
		}

		// Token: 0x170000E2 RID: 226
		// (get) Token: 0x06000493 RID: 1171 RVA: 0x0001C714 File Offset: 0x0001A914
		public override MetadataType MetadataType
		{
			get
			{
				return (MetadataType)this.etype;
			}
		}

		// Token: 0x170000E3 RID: 227
		// (get) Token: 0x06000494 RID: 1172 RVA: 0x0001C72C File Offset: 0x0001A92C
		// (set) Token: 0x06000495 RID: 1173 RVA: 0x00003C19 File Offset: 0x00001E19
		public bool IsNonVariant
		{
			get
			{
				return this.attributes.GetMaskedAttributes(3, 0U);
			}
			set
			{
				this.attributes = this.attributes.SetMaskedAttributes(3, 0U, value);
			}
		}

		// Token: 0x170000E4 RID: 228
		// (get) Token: 0x06000496 RID: 1174 RVA: 0x0001C74C File Offset: 0x0001A94C
		// (set) Token: 0x06000497 RID: 1175 RVA: 0x00003C30 File Offset: 0x00001E30
		public bool IsCovariant
		{
			get
			{
				return this.attributes.GetMaskedAttributes(3, 1U);
			}
			set
			{
				this.attributes = this.attributes.SetMaskedAttributes(3, 1U, value);
			}
		}

		// Token: 0x170000E5 RID: 229
		// (get) Token: 0x06000498 RID: 1176 RVA: 0x0001C76C File Offset: 0x0001A96C
		// (set) Token: 0x06000499 RID: 1177 RVA: 0x00003C47 File Offset: 0x00001E47
		public bool IsContravariant
		{
			get
			{
				return this.attributes.GetMaskedAttributes(3, 2U);
			}
			set
			{
				this.attributes = this.attributes.SetMaskedAttributes(3, 2U, value);
			}
		}

		// Token: 0x170000E6 RID: 230
		// (get) Token: 0x0600049A RID: 1178 RVA: 0x0001C78C File Offset: 0x0001A98C
		// (set) Token: 0x0600049B RID: 1179 RVA: 0x00003C5E File Offset: 0x00001E5E
		public bool HasReferenceTypeConstraint
		{
			get
			{
				return this.attributes.GetAttributes(4);
			}
			set
			{
				this.attributes = this.attributes.SetAttributes(4, value);
			}
		}

		// Token: 0x170000E7 RID: 231
		// (get) Token: 0x0600049C RID: 1180 RVA: 0x0001C7AC File Offset: 0x0001A9AC
		// (set) Token: 0x0600049D RID: 1181 RVA: 0x00003C74 File Offset: 0x00001E74
		public bool HasNotNullableValueTypeConstraint
		{
			get
			{
				return this.attributes.GetAttributes(8);
			}
			set
			{
				this.attributes = this.attributes.SetAttributes(8, value);
			}
		}

		// Token: 0x170000E8 RID: 232
		// (get) Token: 0x0600049E RID: 1182 RVA: 0x0001C7CC File Offset: 0x0001A9CC
		// (set) Token: 0x0600049F RID: 1183 RVA: 0x00003C8A File Offset: 0x00001E8A
		public bool HasDefaultConstructorConstraint
		{
			get
			{
				return this.attributes.GetAttributes(16);
			}
			set
			{
				this.attributes = this.attributes.SetAttributes(16, value);
			}
		}

		// Token: 0x060004A0 RID: 1184 RVA: 0x00003CA1 File Offset: 0x00001EA1
		public GenericParameter(IGenericParameterProvider owner) : this(string.Empty, owner)
		{
		}

		// Token: 0x060004A1 RID: 1185 RVA: 0x0001C7EC File Offset: 0x0001A9EC
		public GenericParameter(string name, IGenericParameterProvider owner) : base(string.Empty, name)
		{
			bool flag = owner == null;
			if (flag)
			{
				throw new ArgumentNullException();
			}
			this.position = -1;
			this.owner = owner;
			this.type = owner.GenericParameterType;
			this.etype = GenericParameter.ConvertGenericParameterType(this.type);
			this.token = new MetadataToken(TokenType.GenericParam);
		}

		// Token: 0x060004A2 RID: 1186 RVA: 0x0001C850 File Offset: 0x0001AA50
		internal GenericParameter(int position, GenericParameterType type, ModuleDefinition module) : base(string.Empty, string.Empty)
		{
			Mixin.CheckModule(module);
			this.position = position;
			this.type = type;
			this.etype = GenericParameter.ConvertGenericParameterType(type);
			this.module = module;
			this.token = new MetadataToken(TokenType.GenericParam);
		}

		// Token: 0x060004A3 RID: 1187 RVA: 0x0001C8A8 File Offset: 0x0001AAA8
		private static ElementType ConvertGenericParameterType(GenericParameterType type)
		{
			ElementType result;
			if (type != GenericParameterType.Type)
			{
				if (type != GenericParameterType.Method)
				{
					throw new ArgumentOutOfRangeException();
				}
				result = ElementType.MVar;
			}
			else
			{
				result = ElementType.Var;
			}
			return result;
		}

		// Token: 0x060004A4 RID: 1188 RVA: 0x0001C1F0 File Offset: 0x0001A3F0
		public override TypeDefinition Resolve()
		{
			return null;
		}

		// Token: 0x04000123 RID: 291
		internal int position;

		// Token: 0x04000124 RID: 292
		internal GenericParameterType type;

		// Token: 0x04000125 RID: 293
		internal IGenericParameterProvider owner;

		// Token: 0x04000126 RID: 294
		private ushort attributes;

		// Token: 0x04000127 RID: 295
		private GenericParameterConstraintCollection constraints;

		// Token: 0x04000128 RID: 296
		private Collection<CustomAttribute> custom_attributes;
	}
}
